package com.ciei.dpagm.util;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;

import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

public class DateUtil {
	public final static long ONE_DAY_TIME = 24 * 60 * 60 * 1000;
	public final static String FORMAT_SHORT = "yyyy-MM-dd";
	public final static String FORMAT_SHORT_CLEAN = "yyyyMMdd";
	public final static String FORMAT_LONG = "yyyy-MM-dd HH:mm:ss";
    public final static String FORMAT_SHORT_OF_DATE = "HH:mm:ss";
	public final static String FORMAT_LONG_NS = "yyyy-MM-dd HH:mm";
	public final static String FORMAT_LONG_CLEAN = "yyyyMMddHHmmss";
	public final static String FORMAT_FULL = "yyyy-MM-dd HH:mm:ss.SSS";
	public final static String FORMAT_FULL_CLEAN = "yyyyMMddHHmmssSSS";
	public final static String FORMAT_SHORT_CN = "yyyy年MM月dd日";
	public final static String FORMAT_SHORT_ABBREVIATION_CN = "yyyy年M月d日";
	public final static String FORMAT_LONG_CN = "yyyy年MM月dd日 HH时mm分ss秒";
	public final static String FORMAT_FULL_CN = "yyyy年MM月dd日 HH时mm分ss秒SSS毫秒";
	public final static String FORMAT_MONTH_DAY_CN = "M月d日";

	public final static String FORMAT_MONTH = "yyyy-MM";
	public final static String FORMAT_YEAR = "yyyy";

	public final static String FORMAT_START_OF_DATE = "yyyy-MM-dd 00:00:00";
	public final static String FORMAT_END_OF_DATE = "yyyy-MM-dd 23:59:59";

	public final static String FORMAT_MONTH_TO_MINUTES_LONG = "MM-dd HH:mm";

    public final static String FORMAT_HOUR_TO_MINUTES_LONG = "HH:mm:ss";

	public final static String FORMAT_HOUR_MINUTE = "HH:mm";

	public final static String FORMAT_HOUR = "HH";

	public final static String TIME_MORNING= "上午";

	public final static String TIME_AFTERNOON = "下午";

	public final static String FORMAT_SHORT_SLASH = "yyyy/MM/dd";

	public final static String FORMAT_LONG_SLASH = "yyyy/MM/dd HH:mm:ss";

	public final static String FORMAT_FULL_SLASH = "yyyy/MM/dd HH:mm:ss.SSS";

	public static final BigDecimal MILLISECONDS_IN_ONE_HOUR = new BigDecimal(TimeUnit.MILLISECONDS.convert(1, TimeUnit.HOURS));
	public static final BigDecimal MILLISECONDS_IN_ONE_DAY = new BigDecimal(TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS));

	public static final SimpleDateFormat FORMAT_SHORT_SDF = new SimpleDateFormat(FORMAT_SHORT);

    public static String dateToString(Date date, String pattern) {
		try {
			return DateFormatUtils.format(date, pattern);
		} catch (Exception e) {
		}
		return null;
	}


	public static Date stringToDate(String date, String pattern) {
		try {
			return DateUtils.parseDate(date, new String[]{pattern});
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public static Date dateToDate(Date date, String pattern) {
    	return stringToDate(dateToString(date,pattern));
	}

	/**
	 * 将日期格式字符串转换为日期（0时0分0秒）
	 * @param dateString	日期格式字符串
	 * @return
	 */
	public static Date stringToStartOfDate(String dateString) {
		if (StringUtils.isNotBlank(dateString)) {
			try {
				Date date = DateUtils.parseDate(dateString, FORMAT_SHORT);
				return DateUtils.parseDate(DateFormatUtils.format(date, FORMAT_START_OF_DATE), FORMAT_LONG);
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	/**
	 * 将日期格式字符串转换为Timestamp（0时0分0秒）
	 * @param dateString	日期格式字符串
	 * @return
	 */
	public static Timestamp stringToStartOfDateTimestamp(String dateString) {
		Date startOfDate = stringToStartOfDate(dateString);
		if (startOfDate != null) {
			return getTimestamp(startOfDate);
		}
		return null;
	}

	/**
	 * 将日期格式字符串转换为日期（23时59分59秒）
	 * @param dateString	日期格式字符串
	 * @return
	 */
	public static Date stringToEndOfDate(String dateString) {
		if (StringUtils.isNotBlank(dateString)) {
			try {
				Date date = DateUtils.parseDate(dateString, FORMAT_SHORT);
				return DateUtils.parseDate(DateFormatUtils.format(date, FORMAT_END_OF_DATE), FORMAT_LONG);
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	/**
	 * <p> 强制格式化时间，按照字符串设定强制格式化时间
	 * <p> Example - 原始时间为2021-03-18 15:21:22，时间格式字符串为yyyy-MM-dd HH:mm:00，返回的格式化后时间为2021-03-18 15:21:00，即强制格式化为00秒
	 *
	 * @param originData		原始时间
	 * @param formatPattern		时间格式字符串
	 * @return					格式化后的时间
	 */
	public static Date forceFormatDate(@NotNull Date originData, @NotNull String formatPattern) {
		try {
			return DateUtils.parseDate(DateFormatUtils.format(originData, formatPattern), FORMAT_LONG);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}

	/**
	 * 将日期格式字符串转换为Timestamp（23时59分59秒）
	 * @param dateString	日期格式字符串
	 * @return
	 */
	public static Timestamp stringToEndOfDateTimestamp(String dateString) {
		Date endOfDate = stringToEndOfDate(dateString);
		if (endOfDate != null) {
			return getTimestamp(endOfDate);
		}
		return null;
	}

	public static Timestamp stringToTimestamp(String date, String pattern) {
		if (StringUtils.isNotBlank(date)) {
			try {
				return new Timestamp(stringToDate(date, pattern).getTime());
			} catch (Exception e) {
			}
		}
		return null;
	}

	public static Timestamp getTimestamp(Date date) {
		try {
			return new Timestamp(date.getTime());
		} catch (Exception e) {
		}
		return null;
	}

	public static int getAge(Date birthDay) {
		if (birthDay == null) {
			return -1;
		}
		Calendar cal = Calendar.getInstance();
		if (cal.before(birthDay)) {
			return -1;
		}
		int yearNow = cal.get(Calendar.YEAR);
		cal.setTime(birthDay);
		int yearBirth = cal.get(Calendar.YEAR);
		int age = yearNow - yearBirth;
		return age;
	}

	public static Date getStartDate(String startTime) {
		try {
			return new SimpleDateFormat(FORMAT_SHORT).parse(startTime);
		} catch (ParseException e) {
		}
		return null;
	}

	public static Date getEndDate(String endTime) {
		Date end = null;
		try {
			end = new SimpleDateFormat(FORMAT_SHORT).parse(endTime);
		} catch (ParseException e) {
		}
		if (end != null) {
			end = new Date(end.getTime() + ONE_DAY_TIME);
		}
		return null;
	}

    /**获取时间相差天数
     * @param startDate
     * @param endDate
     * @return
     * @throws ParseException
     */
	public static int daysBetween(Date startDate, Date endDate) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		startDate = sdf.parse(sdf.format(startDate));
		endDate = sdf.parse(sdf.format(endDate));
		Calendar cal = Calendar.getInstance();
		cal.setTime(startDate);
		long time1 = cal.getTimeInMillis();
		cal.setTime(endDate);
		long time2 = cal.getTimeInMillis();
		long betweenDays = (time2 - time1) / (1000 * 3600 * 24);
		return Integer.parseInt(String.valueOf(betweenDays));
	}

    /**获取时间相差天数(小数点)
     * @param startDate
     * @param endDate
     * @return
     */
    public static BigDecimal betweenDays(Date startDate, Date endDate){
        Calendar cal = Calendar.getInstance();
        cal.setTime(startDate);
        long time1 = cal.getTimeInMillis();
        cal.setTime(endDate);
        long time2 = cal.getTimeInMillis();
        BigDecimal betweenDays = (new BigDecimal(time2).subtract(new BigDecimal(time1))).divide( new BigDecimal(1000 * 3600 * 24),2, BigDecimal.ROUND_HALF_UP);
        return betweenDays;
    }

    /**获取两个时间相差月数
     * @param date1
     * @param date2
     * @return
     */
    public static int getMonths(Date date1, Date date2){
        int iMonth = 0;
        int flag = 0;
        try{
            Calendar objCalendarDate1 = Calendar.getInstance();
            objCalendarDate1.setTime(date1);

            Calendar objCalendarDate2 = Calendar.getInstance();
            objCalendarDate2.setTime(date2);

            if (objCalendarDate2.equals(objCalendarDate1)){
                return 0;
            }
            if (objCalendarDate1.after(objCalendarDate2)){
                Calendar temp = objCalendarDate1;
                objCalendarDate1 = objCalendarDate2;
                objCalendarDate2 = temp;
            }
            if (objCalendarDate2.get(Calendar.DAY_OF_MONTH) < objCalendarDate1.get(Calendar.DAY_OF_MONTH)){
                flag = 1;
            }
            if (objCalendarDate2.get(Calendar.YEAR) > objCalendarDate1.get(Calendar.YEAR)){
                iMonth = ((objCalendarDate2.get(Calendar.YEAR) - objCalendarDate1.get(Calendar.YEAR))
                        * 12 + objCalendarDate2.get(Calendar.MONTH) - flag)
                        - objCalendarDate1.get(Calendar.MONTH);
            } else{
                iMonth = objCalendarDate2.get(Calendar.MONTH)
                        - objCalendarDate1.get(Calendar.MONTH) - flag;
            }

        } catch (Exception e){
            e.printStackTrace();
        }
        return iMonth;
    }
    /**
	 * 获取当前的日期  yyyy-MM-dd
	 */
	public static String getCurrentDateString() {
		Date currentTime = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		String dateString = formatter.format(currentTime);
		return dateString;
	}

	/**
	 * 获取一年前的时间
	 */
	public static String getOneYearAgoDate() {
		Calendar c = Calendar.getInstance();
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		c.setTime(new Date());
		c.add(Calendar.YEAR, -1);
		Date y = c.getTime();
		String year = format.format(y);
		return year;
	}

	/**
	 * 获取前几个月的时间
	 */
	public static String getFewMonthDate(int amount) {
		Calendar c = Calendar.getInstance();
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		c.setTime(new Date());
		c.add(Calendar.MONTH, -amount);
		Date m = c.getTime();
		String mon = format.format(m);
		return mon;
	}

	/**
	 * 获取一个月前的时间
	 */
	public static String getOneMonthAgoDate() {
		Calendar c = Calendar.getInstance();
		//SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		c.setTime(new Date());
		c.add(Calendar.MONTH, -1);
		Date m = c.getTime();
		String mon = format.format(m);
		return mon;
	}

	/**
	 * 日期字符串转calendar
	 */
	public static Calendar getCalendar(String dateStr) {
		Date date = null;
		Calendar calendar = null;
		if (dateStr != null) {
			SimpleDateFormat format = new SimpleDateFormat(FORMAT_SHORT);
			calendar = Calendar.getInstance();
			try {
				date = format.parse(dateStr);
				calendar.setTime(date);
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}
		return calendar;
	}

	/**
	 * 根据calendar，返回当天是周几
	 * weekday就是周几，但是，Java里面坑爹是weekday=1，当天是周日；weekday=2，当天是周一；...;weekday=7，当天是周六
	 */
	public static int getWeekDay(Calendar calendar) {
		int weekDay = calendar.get(Calendar.DAY_OF_WEEK);
		return weekDay;
	}

	/**
	 * 计算两个时间的时间差
	 */
	public static double getDiffOfTwoDate(String start, String end) {
		Date startDate = new Date();
		Date endDate = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat(FORMAT_LONG);
		try {
			startDate = sdf.parse(start);
			endDate = sdf.parse(end);
			long dif = endDate.getTime() - startDate.getTime();
			double d = (double) dif / (1000 * 60 * 60);
			return MathUtil.formatTwoDecimal(d);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return 0;
	}

	/**
	 * java.util.Date 转 sql.date
	 */
	public static java.sql.Date getSqlDate(String date) {
		Date utilDate = getStartDate(date);
		java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());
		return sqlDate;
	}

	/**
	 * 转换成分钟数
	 *
	 * @param time 形如：8:30 的字符串（小时:分钟）
	 * @return
	 */
	public static Integer timeToMinute(String time) {
		if (StringUtils.isNotBlank(time)) {
			String[] times = time.split(":");
			int hour = times.length > 0 ? Integer.parseInt(times[0]) : 0;
			int minute = times.length > 1 ? Integer.parseInt(times[1]) : 0;
			return hour * 60 + minute;
		}
		return 0;
	}

	/**
	 * 分钟数格式化
	 * @param minute 分钟数
	 * @param formatType 0：转换格式为HH:mm ，1：转换格式为HH小时mm分
	 * @return 形如：8:30 或 8小时30分
	 */
	public static String minuteToTime(Integer minute,int formatType) {
		if (minute != null) {
			int hour = minute / 60;
			minute = minute % 60;
			if (formatType == 0) {
				return hour + ":" + minute;
			} else if (formatType == 1) {
				return hour + "小时" + minute + "分";
			}
		}
		return null;
	}

	/**
	 * 将总秒数转换为HH:mm:ss格式
	 * @param totalSecond   总秒数
	 * @return              转换后的时间
	 */
	public static String formatTotalSecondToTime(Integer totalSecond) {
		if (totalSecond == null || totalSecond <= 0) {
			return "00:00:00";
		}

		int sec = totalSecond % 60;
		int minute = totalSecond % 3600 / 60;
		int hour = totalSecond / 3600;
		return String.format("%02d", hour) + ":" +
				String.format("%02d", minute) + ":" +
				String.format("%02d", sec);
	}

	/**
	 * 返回按日分割的Timestamp时间段
	 * @param startTime		开始时间
	 * @param endTime		结束时间
	 * @return				时间段分割点
	 */
	public static List<Timestamp> getDateSeparateTimestampList(Timestamp startTime, Timestamp endTime) {
		List<Timestamp> timestampList = new ArrayList<>();
		if (startTime == null || endTime == null) {
			return timestampList;
		}
		if (startTime.after(endTime)) {
			return timestampList;
		}
		timestampList.add(startTime);
		long endTimeInMillis = endTime.getTime();
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date(startTime.getTime()));
		calendar.add(Calendar.DATE, 1);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		while (calendar.getTimeInMillis() < endTimeInMillis) {
			timestampList.add(new Timestamp(calendar.getTimeInMillis()));
			calendar.add(Calendar.DATE, 1);
		}
		timestampList.add(endTime);

		return timestampList;
	}

	/**
	 * 设置月份第一天零点时间
	 * @param calendar
	 */
	public static void setFirstDayZeroTimeOfMonth(Calendar calendar) {
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
	}

    //获取本月的开始时间
    public static Timestamp getBeginDayOfMonth() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(getNowYear(), getNowMonth() - 1, 1);
        return getDayStartTime(calendar.getTime());
    }

    //获取本月的结束时间
    public static Timestamp getEndDayOfMonth() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(getNowYear(), getNowMonth() - 1, 1);
        int day = calendar.getActualMaximum(5);
        calendar.set(getNowYear(), getNowMonth() - 1, day);
        return getDayEndTime(calendar.getTime());
    }

    //获取本年的开始时间
    public static Timestamp getBeginDayOfYear() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, getNowYear());
        cal.set(Calendar.MONTH, Calendar.JANUARY);
        cal.set(Calendar.DATE, 1);
        return getDayStartTime(cal.getTime());
    }

    //获取本年的结束时间
    public static Timestamp getEndDayOfYear() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, getNowYear());
        cal.set(Calendar.MONTH, Calendar.DECEMBER);
        cal.set(Calendar.DATE, 31);
        return getDayEndTime(cal.getTime());
    }

    //获取某个日期的开始时间
    public static Timestamp getDayStartTime(Date d) {
        Calendar calendar = Calendar.getInstance();
        if(null != d){
            calendar.setTime(d);
        }
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return new Timestamp(calendar.getTimeInMillis());
    }

    //获取某个日期的结束时间
    public static Timestamp getDayEndTime(Date d) {
        Calendar calendar = Calendar.getInstance();
        if(null != d) {
            calendar.setTime(d);
        }
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 23, 59, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return new Timestamp(calendar.getTimeInMillis());
    }

    //获取今年是哪一年
    public static Integer getNowYear() {
        Date date = new Date();
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        return Integer.valueOf(gc.get(1));
    }

    //获取本月是哪一月
    public static int getNowMonth() {
        Date date = new Date();
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        return gc.get(2) + 1;
    }

    //两个日期相减得到的毫秒数
    public static long dateDiff(Date beginDate, Date endDate) {
        long date1ms = beginDate.getTime();
        long date2ms = endDate.getTime();
        return date2ms - date1ms;
    }

    //获取某年某月的第一天日期
    public static Date getStartMonthDate(int year, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, month - 1, 1);
        return calendar.getTime();
    }

    //获取某年某月的最后一天日期
    public static Date getEndMonthDate(int year, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, month - 1, 1);
        int day = calendar.getActualMaximum(5);
        calendar.set(year, month - 1, day);
        return calendar.getTime();
    }

    public static Timestamp addDate(  Date date, long day) throws ParseException {
      /*  SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); // 日期格式
        Date date = dateFormat.parse(timeParam); // 指定日期*/

        long time = date.getTime(); // 得到指定日期的毫秒数
        day = day * 24 * 60 * 60 * 1000; // 要加上的天数转换成毫秒数
        time += day; // 相加得到新的毫秒数
        Timestamp timestamp = new Timestamp(time);
        return timestamp; // 将毫秒数转换成日期
    }

    public static Integer getYears(Date startTimeStamp, Date endTimestamp) {
        Calendar calendarYear = Calendar.getInstance();
        calendarYear.setTime(startTimeStamp);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(endTimestamp);
        Integer i = calendar.get(Calendar.YEAR) - calendarYear.get(Calendar.YEAR);
        return i;
    }

	/**
	 * 将时间字符串根据不同的长度转换为不同格式的日期
	 * 注:目前只转换精确到日、月、年，按需补充,默认为精确到秒
	 * @Author: pp
	 * @Date: 2021/6/10
	 * @param date 开始时间字符串
	 * @return 转换后的时间
	 **/
	public static Date stringToDate(String date){
		try {
			if(date.length() == 4){
				return DateUtils.parseDate(date,DateUtil.FORMAT_YEAR);
			}else if(date.length() >4 && date.length() <= 7){
				return DateUtils.parseDate(date,DateUtil.FORMAT_MONTH);
			}else if(date.length() >7 && date.length() <= 10){
				return DateUtils.parseDate(date,DateUtil.FORMAT_SHORT);
			}else{
				return DateUtils.parseDate(date,DateUtil.FORMAT_LONG);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	/**
	 * 将时间字符串根据不同的长度转换为不同格式的日期
	 * 注:1.目前只转换精确到日、月、年，按需补充
	 * 	  2.如月份:应精确到月份的最后一天
	 * @Author: pp
	 * @Date: 2021/6/10
	 * @param endDate 时间字符串
	 * @return 转换后的时间
	 **/
	public static Date endDateStringToDate(String endDate){
		try {
			if(endDate.length() == 4){
				return getYearLastDate(endDate);
			}else if(endDate.length() >4 && endDate.length() <= 7){
				return getYearMonthLastDate(endDate);
			}else if(endDate.length() >7 && endDate.length() <= 10){
				return stringToEndOfDate(endDate);
			}else{
				return null;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 将时间字符串根据不同的长度转换为精确到时分秒时间
	 * 注:目前只转换精确到日、分，按需补充,默认为精确到秒
	 * @Author: pp
	 * @Date: 2021/6/10 11
	 * @param dateString 开始时间字符串
	 * @return 转换后的时间
	 **/
	public static Date stringToLongDate(String dateString){
		try {
			if(dateString.length() >7 && dateString.length() <= 10){
				Date date = DateUtils.parseDate(dateString, FORMAT_SHORT);
				return DateUtils.parseDate(DateFormatUtils.format(date, FORMAT_START_OF_DATE), FORMAT_LONG);
			}else if (dateString.length() >13 && dateString.length() <= 16){
				Date date = DateUtils.parseDate(dateString, FORMAT_LONG_NS);
				return DateUtils.parseDate(DateFormatUtils.format(date, FORMAT_LONG_NS + ":00"), FORMAT_LONG);
			}else{
				return DateUtils.parseDate(dateString,DateUtil.FORMAT_LONG);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

    /**
     * 根据传入的年份获取该年份的第一天时间,精确到时分秒
     * @return String
     * **/
    public static Date getYearFirstDate(String year) throws ParseException {
        return  DateUtils.parseDate(year+"-01-01 00:00:00",DateUtil.FORMAT_LONG);

    }

    /**
     * 根据传入的年份获取该年份的最后一天时间,精确到时分秒
     * @return String
     * **/
    public static Date getYearLastDate(String year) throws ParseException {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR,Integer.valueOf(year));
        calendar.set(Calendar.MONTH,calendar.getActualMaximum(Calendar.MONTH));
        calendar.set(Calendar.DAY_OF_MONTH,calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        calendar.set(Calendar.HOUR,23);
		calendar.set(Calendar.MINUTE,59);
		calendar.set(Calendar.SECOND,59);
		Date currYearLast = calendar.getTime();
        return  DateUtils.parseDate(new SimpleDateFormat(DateUtil.FORMAT_LONG).format(currYearLast),DateUtil.FORMAT_LONG);

    }

    /**
     * 根据传入的年月份获取该年月份的第一天时间,精确到时分秒
     * @return String
     * **/
    public static Date getYearMonthFirstDate(String yearMonth) throws ParseException {
        return  DateUtils.parseDate(yearMonth + "-01  00:00:00",DateUtil.FORMAT_LONG);
    }

    /**
     * 根据传入的年月份获取该月份的最后一天时间,精确到时分秒
     * @return String
     * **/
    public static Date getYearMonthLastDate(String yearMonth) throws ParseException {
        String[] yearMonthArr = yearMonth.split("-");
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR,Integer.valueOf(yearMonthArr[0]));
		//该结果会将月份+1，故进行减一操作
        calendar.set(Calendar.MONTH ,Integer.valueOf(yearMonthArr[1]) -1 );
        calendar.set(Calendar.DAY_OF_MONTH,calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
		calendar.set(Calendar.HOUR,23);
		calendar.set(Calendar.MINUTE,59);
		calendar.set(Calendar.SECOND,59);
        Date currYearMonthLast = calendar.getTime();
        return  DateUtils.parseDate(new SimpleDateFormat(DateUtil.FORMAT_LONG).format(currYearMonthLast),DateUtil.FORMAT_LONG);
    }

	/**
	 * 获取两个时间节点之间的月份列表
	 * @Author: pp
	 * @Date: 2021/7/10
	 * @param
	 * @return
	 */
	public static List<String> getMonthListByBetween(Date startDate, Date endDate) throws ParseException {
		ArrayList<String> result = new ArrayList<String>();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
		String startDateStr = sdf.format(startDate);
		String endDateStr = sdf.format(endDate);
		Calendar start = Calendar.getInstance();
		Calendar end = Calendar.getInstance();
		start.setTime(sdf.parse(startDateStr));
		start.set(start.get(Calendar.YEAR), start.get(Calendar.MONTH), 1);
		end.setTime(sdf.parse(endDateStr));
		end.set(end.get(Calendar.YEAR), end.get(Calendar.MONTH), 2);
		Calendar curr = start;
		while (curr.before(end)) {
			result.add(sdf.format(curr.getTime()));
			curr.add(Calendar.MONTH, 1);
		}

		return result;
	}

	/**
	 * 根据日期获取年份
	 * @param date
	 * @return
	 */
	public static int getYearByDate(Date date){
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.YEAR);
	}
	/**
	 * 根据日期获取月份
	 * @param date
	 * @return
	 */
	public static int getMonthByDate(Date date){
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.MONTH)+1;
	}

	/**
	 * 根据日期获取第几日
	 * @param date
	 * @return
	 */
	public static int getDayByDate(Date date){
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.DAY_OF_MONTH);
	}


	/**
	 * 根据日期判断是否是当前季度最后一个月
	 *
	 */
	public static Boolean isQuarterLastMonth(Date date) {
		int month = getMonthByDate(date);
		if (month == 3 || month == 6 || month== 9 || month ==12) {
			return true;
		}
		return false;
	}

	/**
	 * 判断是否是当前半年周期最后一个月
	 *
	 */
	public static Boolean isHalfYearLastMonth(Date date) {
		int month = getMonthByDate(date);
		if ( month == 6) {
			return true;
		}
		return false;
	}

	/**
	 * 判断是否是当年最后一个月
	 *
	 */
	public static Boolean isYearLastMonth(Date date) {
		int month = getMonthByDate(date);
		if ( month == 12) {
			return true;
		}
		return false;
	}

	/**
	 * @Description: 获取指定日期第n秒前后的日期
	 **/
	public static Date getDateAfterNumberSecond(Date date,Integer second) {
		Calendar startCalendar = Calendar.getInstance();
		startCalendar.setTime(date);
		startCalendar.add(Calendar.SECOND, second);
		Date startDate = startCalendar.getTime();
		return startDate;
	}

	/**
	 * @Description: 获取指定日期第n天后的日期
	 **/
	public static Date getDateAfterNumberDays(Date date,Integer days) {
		Calendar startCalendar = Calendar.getInstance();
		startCalendar.setTime(date);
		startCalendar.add(Calendar.DATE, days);
		Date startDate = startCalendar.getTime();
		return startDate;
	}

	/**
	 * @Description: 获取指定日期所属月第n天
	 **/
	public static Date getMonthNumberDays(Date date,Integer days) {
		Calendar startCalendar = Calendar.getInstance();
		startCalendar.setTime(date);
		startCalendar.set(Calendar.DAY_OF_MONTH, days);
		Date startDate = startCalendar.getTime();
		return startDate;
	}

	/**
	 * @Description: 获取季度初月第n天
	 * 1.根据给定日期计算当前季度的第一个月份
	 * 2.设置日历的月份为当前季度的第一个月份
	 * 3.最后设置日历月份天数为第一天即可
	 **/
	public static Date getQuarterFirstMonthNumberDays(Date date,Integer days) {
		Calendar startCalendar = Calendar.getInstance();
		startCalendar.setTime(date);
		//get方法：获取给定日历属性的值，如 endCalendar.get(Calendar.MONTH) 获取日历的月份
		//计算季度数：由于月份从0开始，即1月份的Calendar.MONTH值为0,所以计算季度的第一个月份只需 月份 / 3 * 3
		startCalendar.set(Calendar.MONTH, (((int) startCalendar.get(Calendar.MONTH)) / 3) * 3);
		startCalendar.set(Calendar.DAY_OF_MONTH, days);
		Date startDate = startCalendar.getTime();
		return startDate;
	}

	/**
	 * @Description: 获取季度末月第n天
	 **/
	public static Date getQuarterLastMonthNumberDays(Date date,Integer days) {
		Calendar startCalendar = Calendar.getInstance();
		startCalendar.setTime(date);
		startCalendar.set(Calendar.MONTH, ((((int) startCalendar.get(Calendar.MONTH)) / 3) * 3)+2);
		startCalendar.set(Calendar.DAY_OF_MONTH, days);
		Date startDate = startCalendar.getTime();
		return startDate;
	}

	/**
	 * @Description: 获取半年度初月第n天
	 **/
	public static Date getHalfYearFirstMonthDays(Date date,Integer days) {
		Calendar startCalendar = Calendar.getInstance();
		startCalendar.setTime(date);
		startCalendar.set(Calendar.MONTH, (((int) startCalendar.get(Calendar.MONTH)) / 6) * 6);
		startCalendar.set(Calendar.DAY_OF_MONTH, days);
		Date startDate = startCalendar.getTime();
		return startDate;
	}

	/**
	 * @Description: 获取半年度末月第n天
	 **/
	public static Date getHalfYearLastMonthDays(Date date,Integer days) {
		Calendar startCalendar = Calendar.getInstance();
		startCalendar.setTime(date);
		startCalendar.set(Calendar.MONTH, ((((int) startCalendar.get(Calendar.MONTH)) / 6) * 6)+5);
		startCalendar.set(Calendar.DAY_OF_MONTH, days);
		Date startDate = startCalendar.getTime();
		return startDate;
	}

	/**
	 * @Description: 获取年初月第n天
	 **/
	public static Date getFirstMonthDays(Date date,Integer days) {
		Calendar startCalendar = Calendar.getInstance();
		startCalendar.setTime(date);
		startCalendar.set(Calendar.MONTH, (((int) startCalendar.get(Calendar.MONTH)) / 12) * 12);
		startCalendar.set(Calendar.DAY_OF_MONTH, days);
		Date startDate = startCalendar.getTime();
		return startDate;
	}

	/**
	 * @Description: 获取年末月第n天
	 **/
	public static Date getLastMonthDays(Date date,Integer days) {
		Calendar startCalendar = Calendar.getInstance();
		startCalendar.setTime(date);
		startCalendar.set(Calendar.MONTH, ((((int) startCalendar.get(Calendar.MONTH)) / 12) * 12)+11);
		startCalendar.set(Calendar.DAY_OF_MONTH, days);
		Date startDate = startCalendar.getTime();
		return startDate;
	}

	/**
	 * 判断给定时间是上午还是下午
	 * @param date
	 * @return
	 */
	public static String judgeMorningOrAfternoon(Date date){
		String hourStr = DateFormatUtils.format(date, FORMAT_HOUR);
		int hour = Integer.parseInt(hourStr);
		if (hour<12){
			return TIME_MORNING;
		}else {
			return TIME_AFTERNOON;
		}
	}

	/**
	 * 获取当日开始时间
	 * @param time 时间
	 */
	public static Date getStartTimeOfDay(Date time) {
		return DateUtils.truncate(time, Calendar.DATE);
	}

	/**
	 * 根据月份获取属于第几季度
	 * @param month
	 * @return
	 */
	public static int getQuarterByMonth(int month){
		int quarter = 0;
		if (month <= 3){
			quarter = 1;
		}else if (month <=6){
			quarter = 2;
		}else if (month <=9){
			quarter = 3;
		}else if (month <= 12){
			quarter = 4;
		}
		return  quarter;
	}

	/**
	 * 设定一天结束
	 * @param date
	 * @return
	 */
	public static Date setEndOfDay(Date date){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		return calendar.getTime();
	}

	/**
	 * 设定下一天的开始
	 * @param date
	 * @return
	 */
	public static Date setNextStartOfDay(Date date){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DAY_OF_MONTH,1);
		calendar.set(Calendar.MINUTE, 00);
		calendar.set(Calendar.SECOND, 00);
		return calendar.getTime();
	}

	/**
	 * 获取时间相差天数
	 * @param startDate
	 * @param endDate
	 */
	public static int getTimeDifferenceDays(Date startDate, Date endDate) throws IllegalArgumentException {
		if (startDate.after(endDate)) {
			throw new IllegalArgumentException();
		}
		return (int) TimeUnit.DAYS.convert(endDate.getTime() - startDate.getTime(), TimeUnit.MILLISECONDS) + 1;
	}

	/**
	 * 获取当日最后时间
	 * @param time 时间
	 */
	public static Date getEndTimeOfDay(Date time) {
		return DateUtils.addMilliseconds(DateUtils.addDays(getStartTimeOfDay(time), 1), -1);
	}

	/**
	 * 日期转换为cron
	 * @param date
	 * @return
	 */
	public static String dateToCron(Date date){
		Calendar ca = Calendar.getInstance();
		ca.setTime(date);
		int seconds = ca.get(Calendar.SECOND) ;
		int minutes = ca.get(Calendar.MINUTE);
		int hours = ca.get(Calendar.HOUR_OF_DAY);
		int day = ca.get(Calendar.DAY_OF_MONTH);
		int month = ca.get(Calendar.MONTH) + 1;
		int year = ca.get(Calendar.YEAR);
		String cron = seconds + " " + minutes + " " + hours + " " + day + " " + month + " ? " + year;
		return cron;
	}


}
